# coding=utf-8

import logging
from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler

from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.memory import MemoryJobStore
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from sqlalchemy import create_engine
from mmonitor.common.config import mysql_db, mysql_password, mysql_server, mysql_user, mysql_port, rpc_port, rpc_host
from mmonitor.utils.log import init_logger

logger = logging.getLogger("apscheduler")


class Scheduler(object):
    def __init__(self):
        mysql_url = 'mysql+pymysql://%s:%s@%s:%s/%s?charset=utf8' % (mysql_user,
                                                                     mysql_password,
                                                                     mysql_server,
                                                                     mysql_port,
                                                                     mysql_db)
        jobstores = {
            'default': SQLAlchemyJobStore(engine=create_engine(mysql_url,
                                                               encoding='utf-8',
                                                               pool_recycle=10,
                                                               echo=False)),
            'memory': MemoryJobStore()
        }
        self.scheduler = BackgroundScheduler(
            timezone='Asia/Shanghai',
            jobstores=jobstores,
            job_defaults=dict(misfire_grace_time=24*3600))
        self._add_event_listener()
        self.scheduler.start()

    def _add_event_listener(self):
        from apscheduler import events

        def job_executed_listener(event):
            job_id = event.job_id
            if event.code == events.EVENT_JOB_MISSED:
                logger.error("[%s] missed a task", job_id)
            else:
                task_id = event.retval
                exception = event.exception
                if exception:
                    logger.error("[%s] deliver task %s failed: %s", job_id, task_id, exception)
                else:
                    logger.info("[%s] deliver task %s success", job_id, task_id)
        self.scheduler.add_listener(job_executed_listener,
            events.EVENT_JOB_MISSED | events.EVENT_JOB_EXECUTED)

    def add_job(self, func, **kwargs):
        logging.info("get :{}".format(kwargs))
        job = self.scheduler.add_job(func, **kwargs)
        return {'trigger': str(job.trigger)}

    def remove_job(self, job_id):
        self.scheduler.remove_job(job_id)
        return 'ok'

    def reschedule_job(self, job_id, kwargs):
        self.scheduler.reschedule_job(job_id, **kwargs)
        return 'ok'

    def pause_job(self, job_id):
        self.scheduler.pause_job(job_id)
        return 'ok'

    def resume_job(self, job_id):
        self.scheduler.resume_job(job_id)
        return 'ok'


class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RPC2',)

server = SimpleXMLRPCServer((rpc_host, rpc_port),
                            requestHandler=RequestHandler)
server.register_introspection_functions()
init_logger("DEBUG")
logger.info("start scheduler")
server.register_instance(Scheduler())
server.serve_forever()
# s = Scheduler()
# from mmonitor.main.spider import run_job
#
# s.add_job(run_job, 'interval', seconds=5, args=['a','b','list'])
